package br.com.ps.bombertournament.game.scene;

import java.net.URL;

import br.com.ps.bombertournament.App;
import br.com.ps.bombertournament.game.Layer;
import br.com.ps.bombertournament.game.MappedScene;
import br.com.ps.bombertournament.game.object.Empty;
import br.com.ps.bombertournament.game.object.Player;
import br.com.ps.bombertournament.game.object.Player.Keyboard;

import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;

public class BattleScene extends MappedScene implements InputProcessor {

	private static final int CONTROLLER_LAYER_LEVEL = 9;
	private String configurations;

	private int testPosition = 1;
	private Player player;
	
	private Layer virtualController;
	private Empty controller;
	private Empty buttonBomb;
	private int controllerMousePointer = -1;
	private int buttonBombMousePointer = -1;
	private int controllerXPointZero = 0;
	private int controllerYPointZero = 0;
	
	public BattleScene() {
	}

	public BattleScene(String configurations) {
		this.configurations = configurations;
	}

	public void create() {
		super.create();

		player = nextObject();
		if (super.getGame().getMusic() != null) {
			super.getGame().getMusic().play();
		}
		
		
		{ // Adding the virtual controller
			Gdx.input.setInputProcessor(this);
			
			addVirtualControllerLayer();
		}
	}

	@Override
	public String getMapPath() {
		return configurations;
	}

	private Player nextObject() {
		String id = String.format("PLAYER_%s", testPosition++);
		Player result = (Player) super.getGame().findObjectById(id);

		if (result == null) {
			testPosition = 1;
			result = nextObject();
		} else {
			System.out.println(id);
		}

		return result;
	}

	@Override
	public boolean keyDown(int keycode) {
		boolean result = false;
		
		if (keycode == Input.Keys.DOWN) {
			result = player.processEvent(Keyboard.DOWN);
		}
		if (keycode == Input.Keys.UP) {
			result = player.processEvent(Keyboard.UP);
		}
		if (keycode == Input.Keys.RIGHT) {
			result = player.processEvent(Keyboard.RIGHT);
		}
		if (keycode == Input.Keys.LEFT) {
			result = player.processEvent(Keyboard.LEFT);
		}
		
		if (keycode == Input.Keys.SPACE || keycode == Input.Keys.DPAD_CENTER) {
			result = player.processEvent(Keyboard.SPACE);
		}
		
		if (result == false) {
			if (App.LOG_LEVEL == Application.LOG_INFO)
			Gdx.app.log(App.name, String.format("Keycode: %s", keycode));
		}
		
		return result;
	}

	@Override
	public boolean keyUp(int keycode) {
		// Do nothing
		return false;
	}

	@Override
	public boolean keyTyped(char character) {
		// Do nothing
		return false;
	}

	@Override
	public boolean touchDown(int x, int y, int pointer, int button) {
		boolean handled = false;
		
		if (controller.instercept(x, Gdx.graphics.getHeight() - y)) {
			controllerMousePointer = pointer;
			readTouchController(x, y);
		}
		
		if (buttonBomb.instercept(x, Gdx.graphics.getHeight() - y)) {
			buttonBombMousePointer = pointer;
			player.processEvent(Keyboard.SPACE);
		}
		
		return handled;
	}

	@Override
	public boolean touchUp(int x, int y, int pointer, int button) {
		boolean handled = false;
		
		if (controllerMousePointer == pointer) {
			controllerMousePointer = -1;
		}
		
		if (buttonBombMousePointer == pointer) {
			buttonBombMousePointer = -1;
		}
		
		return handled;
	}

	@Override
	public boolean touchDragged(int x, int y, int pointer) {
		boolean handled = false;
		
		if (controllerMousePointer == pointer) {
			readTouchController(x, y);
			handled = true;
		}
		
		return handled;
	}

	@Override
	public boolean touchMoved(int x, int y) {
		// Do nothing
		return false;
	}

	@Override
	public boolean scrolled(int amount) {
		// Do nothing
		return false;
	}
	
	/**
	 * Add the virtual controller layer
	 */
	private void addVirtualControllerLayer() {
		virtualController = new Layer(super.getGame());
		
		{ // Adding controller
			controller = new Empty("data/world/controller/controller.json");
			controller.loadAnimations();
			controller.setPosition( Gdx.graphics.getWidth() * 0.03F, Gdx.graphics.getHeight() * 0.04F);
			
			virtualController.add(controller);
		}
		
		{ // Adding button bomb
			buttonBomb = new Empty("data/world/controller/button_bomb.json");
			buttonBomb.loadAnimations();
			buttonBomb.setPosition( Gdx.graphics.getWidth() - buttonBomb.getRegionWidth() - (Gdx.graphics.getWidth() * 0.03F), (Gdx.graphics.getHeight() * 0.04F));
			
			virtualController.add(buttonBomb);
		}
		
		{ // Calculation of point zeros
			controllerXPointZero = Math.round((controller.getRegionWidth() / 2) + controller.getX());
			controllerYPointZero = Math.round((Gdx.graphics.getHeight() - controller.getY()) - (controller.getRegionHeight() / 2));
		}
		
		super.getGame().addLayer(CONTROLLER_LAYER_LEVEL,  virtualController);
	}
	
	/**
	 * Interprets the touch on the screen and tell to player the direction to walk
	 * 
	 * @param x Pointer X of the touch event
	 * @param y Pointer Y of the touch event
	 */
	private void readTouchController(int x, int y) {
		int draggedX = x - controllerXPointZero;
		int draggedY = y - controllerYPointZero;

		Keyboard primaryKeyCode  = null;
		double degrees = Math.round(Math.atan2(draggedY, draggedX) * 180/Math.PI);
		
		if (degrees <= 45 && degrees >= -45) {
			primaryKeyCode = Keyboard.RIGHT;
		} else if (degrees <= 135 && degrees >= 45) {
			primaryKeyCode = Keyboard.DOWN;
		} else if (degrees >= -135 && degrees <= -45) {
			primaryKeyCode = Keyboard.UP;
		} else if (degrees <= 135 || degrees >= -135) {
			primaryKeyCode = Keyboard.LEFT;
		}

//		Keyboard primaryKeyCode  = null;
//		Keyboard secondaryKeyCode = null;
//		if(degrees >= -22 && degrees <= 22) {
//			primaryKeyCode = Keyboard.RIGHT;
//		// Thumb stick position - Down
//		} else if (degrees >= 68 && degrees <= 112) {
//			primaryKeyCode = Keyboard.DOWN;
//		// Thumb stick position - Left
//		} else if((degrees >= 158 && degrees <= 180) || (degrees >= -179 && degrees <= -158)) {
//			primaryKeyCode = Keyboard.LEFT;
//		// Thumb stick position - Up			
//		} else if(degrees >= -112 && degrees <= -68) {
//			primaryKeyCode = Keyboard.UP;
//		// Thumb stick position - Up/Left
//		} else if(degrees >= -157 && degrees <= -113) {
//			primaryKeyCode = Keyboard.UP;
//			secondaryKeyCode = Keyboard.LEFT;
//		// Thumb stick position - Down/Left
//		} else if(degrees <= 157 && degrees >= 113) {
//			primaryKeyCode = Keyboard.DOWN;
//			secondaryKeyCode = Keyboard.LEFT;
//		// Thumb stick position - Up/Right
//		} else if(degrees >=-67 && degrees <= -21) {
//			primaryKeyCode = Keyboard.UP;
//			secondaryKeyCode = Keyboard.RIGHT;
//		// Thumb stick position - Down/Right
//		} else if(degrees >= 23 && degrees <= 67) {
//			primaryKeyCode = Keyboard.DOWN;
//			secondaryKeyCode = Keyboard.RIGHT;
//		}
		player.processEvent(primaryKeyCode);
	}
}
